import { animated, useTransition } from "@react-spring/web"
import { CSSProperties, FC, PropsWithChildren, useEffect, useMemo, useRef } from "react"
import Overlay from "./Overlay"
import React from "react"
import classNames from "classnames"

const DURATION = 300

interface SlideInOverlayProps extends PropsWithChildren {
    isVisible: boolean
    from?: "right" | "bottom"
    className?: string | string[]
    style?: CSSProperties
    onEnter?: () => void
    onExit?: () => void
}

export const SlideInOverlay: FC<SlideInOverlayProps> = (props) => {
    const { isVisible, from = 'right', children, style, className, onEnter, onExit } = props
    const visibleRef = useRef(isVisible);
    const x = useMemo(() => {
        if (from === 'right') {
            return window.screen.width
        } else {
            return window.screen.height
        }
    }, [from])
    const transitions = useTransition(isVisible, {
        // 进入动画开始
        from: {
            x,
            opacity: 1
        },
        // 进入动画结束
        enter: {
            x: 0,
            opacity: 1
        },
        // 离开动画结束
        leave: {
            x,
            opacity: 0
        },
        config: { duration: DURATION },

    })

    const translate = React.useCallback(
        (x: number) => {
            switch (from) {
                case "right":
                    return `translateX(${x}px)`;
                case "bottom":
                    return `translateY(${x}px)`;
            }
        },
        [from]
    );

    useEffect(() => {
        let timer: NodeJS.Timeout;

        if (isVisible === true && onEnter != null) {
            timer = setTimeout(onEnter, DURATION);
        }

        return () => {
            if (timer != null) {
                clearTimeout(timer);
            }
        };
    }, [isVisible, onEnter]);

    useEffect(() => {
        let timer: NodeJS.Timeout;

        if (isVisible === false && visibleRef.current === true && onExit != null) {
            timer = setTimeout(onExit, DURATION);
        }

        visibleRef.current = isVisible;
        
        return () => {
            if (timer != null) {
                clearTimeout(timer);
            }
        };
    }, [isVisible, onExit]);

    return (
        <>
            {transitions(
                (props, isVisible) =>
                    isVisible && (
                        <Overlay
                            as={animated.div}
                            className={classNames(className)}
                            style={{
                                ...style,
                                transform: props.x.to((x) => (x === 0 ? "none" : translate(x))),
                                opacity: props.opacity,
                            }}
                        >
                            {children}
                        </Overlay>
                    )
            )}
        </>
    )
}